require('source-map-support').install({
	environment: 'node'
});
import {entityConfig} from "./EntityConfig";
import * as fs from "fs";
import {ContextData, EntityComponent, EntityData} from "./EntityData";
let ejs = require('ejs')
import path = require("path");
let dir = __dirname.replace("/dist","/src")
type Components =  {
	[key: string]: EntityComponent
}

type ContextsData = {
	[key: string]: ContextData;
}
export class EntityParser{
	configPath : string = ""
	scriptPath : string = ""
	language : string = ""
	tag : string = ""
	parserTag : string = ""
	contexts : {}
	templatePath : string = ""
	baseConfigFile : string = ""
	source : string = ""
	outPut : string = ""
	fileSuffix : string = ""
	nameSpace : string = ""

	entityData : EntityData
	components : Components  = {}
	contextsData  :ContextsData = {}

	beforeGenerate(){
		this.templatePath = path.join(dir, "template")
		this.initData()
		this.initContextsData()
	}

	initData(){
		var outPut = entityConfig.output
		if (fs.existsSync(outPut)){
			fs.rmdirSync(outPut, {
				recursive: true  //是否递归,默认false
			})
		}
		fs.mkdirSync(outPut, {
			recursive: true  //是否递归,默认false
		})
		this.outPut = outPut

		if (!fs.existsSync(entityConfig.entityExportData)){
			console.error("[entity] entity生成数据不存在")
		}
		let jsonData = JSON.parse(fs.readFileSync(entityConfig.entityExportData, "utf8"))
		this.components = jsonData["components"]
		this.entityData = jsonData["entityData"]
	}

	initContextsData(){
		for (let key in this.components) {
			var value = this.components[key]
			if (this.contextsData[value.tag] == undefined){
				this.contextsData[value.tag] = new ContextData()
				this.contextsData[value.tag].name = value.tag[0].toLowerCase() + value.tag.substring(1, value.tag.length)
				this.contextsData[value.tag].Name = value.tag[0].toUpperCase() + value.tag.substring(1, value.tag.length)
			}
			this.contextsData[value.tag].comps.push(value)
			value.Name = value.name
			value.name = key[0].toLowerCase() + key.substring(1, key.length)
		}
	}

	renderTemplate(fileName : string, templateFileName : string, data = undefined){
		let file = fs.readFileSync(path.join(this.templatePath,   templateFileName +".ejs"), 'utf-8')
		let inData = {
		}
		if (data != undefined){
			inData = Object.assign(inData, data)
		}
		let ret : string = ejs.render(file,inData)
		ret = ret.replace(/&lt;/g, "<").replace(/&gt;/g, ">")
			.replace(/&amp;lt/g,"<").replace(/&amp;gt/g,">")
			.replace(/&amp;lt;/g,"<").replace(/&amp;gt;/g,">")
			.replace(/&#34;/g,'"')
		fs.writeFileSync(path.join(this.outPut, fileName), ret)
		return ret;
	}

	generateContext(){
		let tag2CompsMap = this.contextsData
		for (let key in tag2CompsMap) {
			var value = tag2CompsMap[key]
			let ret = this.renderTemplate(key + "Context" + '.ts' , "Context",{
				contextData : value,
				contextName : value.name,
				ContextName : value.Name,
				source : "./"
			})
			console.log(ret)
		}
	}

	generateComponent(){
		let tag2CompsMap = this.contextsData
		for (let key in tag2CompsMap) {
			var value = tag2CompsMap[key]
			let ret = this.renderTemplate(key + "ComponentIds" + '.ts' , "ComponentIds",{
				contextData : value,
				contextName : value.name,
				ContextName : value.Name,
				source : "./"
			})
			console.log(ret)
		}

	}

	generateEntity(){
		let tag2CompsMap = this.contextsData
		for (let key in tag2CompsMap) {
			var value = tag2CompsMap[key]
			let ret = this.renderTemplate(key + "Entity" + '.ts' , "Entity",{
				contextData : value,
				contextName : value.name,
				ContextName : value.Name,
				source : "./"
			})
		}
	}

	generateMatcher(){
		let tag2CompsMap = this.contextsData
		for (let key in tag2CompsMap) {
			var value = tag2CompsMap[key]
			let ret = this.renderTemplate(key + "Matcher" + '.ts' , "Matcher",{
				contextData : value,
				contextName : value.name,
				ContextName : value.Name,
				source : "./"
			})
			console.log(ret)
		}
	}

	generateAttrs(){

	}

	generateAutoInc(){

	}

	generate(){
		this.beforeGenerate()
		this.generateContext()
		this.generateComponent()
		this.generateEntity()
		this.generateMatcher()
		this.generateAttrs()
		this.generateAutoInc()
	}
}

let p = new EntityParser()
p.generate()